#ifndef _ICELL_H
#define _ICELL_H

#include <iostream>

template<int t_iDimPoint, typename t_Type> class Point;

class VirtualICell
{
	public:
		//virtual int GetDim() const = 0;
		virtual const VirtualICell* GetBorderCells() const = 0;
		virtual void Display() = 0;
};


// ===============================================================
//  Déclaration de la classe i-cellule : ICell
// ===============================================================

template<int t_iDimCell, int t_iDimPoint, typename t_Type>
class ICell : public VirtualICell
{
	public:
		ICell();
		~ICell();
		
		//int GetDim() const { return t_iDimCell; }
		const ICell<t_iDimCell - 1, t_iDimPoint, t_Type>* GetBorderCells() const { return m_picBorderCells; }
		void Display();

	private:
		ICell<t_iDimCell - 1, t_iDimPoint, t_Type>* m_picBorderCells[2 * t_iDimCell];
};



// ===============================================================
//  Spécialisation de i-cellule pour les cellules de dimmension 0.
// ===============================================================

template<int t_iDimPoint, typename t_Type>
class ICell<0, t_iDimPoint, t_Type> : public VirtualICell
{
	public:
		ICell() : m_pPoint(new Point<t_iDimPoint, t_Type>()) {}
		~ICell() { delete m_pPoint; }
		
		const ICell<0, t_iDimPoint, t_Type>* GetBorderCells() const { return 0; }
		const Point<t_iDimPoint, t_Type>* GetPoint() const { return m_pPoint; }
		void Display();
		
	private:
		Point<t_iDimPoint, t_Type>* m_pPoint;
};



// ===============================================================
//  Implantation des fonctions membres.
// ===============================================================

template<int t_iDimCell, int t_iDimPoint, typename t_Type>
ICell<t_iDimCell, t_iDimPoint, t_Type>::ICell()
{
	//std::cout << "Je construit la cellule de dimmension " << t_iDimCell << std::endl;
	for(int i = 0; i < 2 * t_iDimCell; i++)
		m_picBorderCells[i] = new ICell<t_iDimCell - 1, t_iDimPoint, t_Type>();
}


// ---------------------------------------------------------------
template<int t_iDimCell, int t_iDimPoint, typename t_Type>
ICell<t_iDimCell, t_iDimPoint, t_Type>::~ICell()
{
	for (int i = 0; i < 2 * t_iDimCell; i++)
		delete m_picBorderCells[i];
}


// ---------------------------------------------------------------
template<int t_iDimCell, int t_iDimPoint, typename t_Type>
void ICell<t_iDimCell, t_iDimPoint, t_Type>::Display()
{
	std::cout << "Dimmension " << t_iDimCell << std::endl;
	for (int i = 0; i < 2 * t_iDimCell; i++)
		m_picBorderCells[i]->Display();
}


// ---------------------------------------------------------------
template<int t_iDimPoint, typename t_Type>
void ICell<0, t_iDimPoint, t_Type>::Display()
{
	std::cout << "Dimmension 0" << std::endl;
	for (int i = 0; i < t_iDimPoint; i++)
		std::cout << "point " << i << " : " << m_pPoint->GetCoordonate(i) << std::endl;
}


#endif // _ICELL_H
